-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PoC Bucketed rate limit #168
base: fs/branch_9_3
Are you sure you want to change the base?
Conversation
@noblepaul The |
Couple of questions
|
The request header requirement is something we may be able to get rid of. the only reason it is there is because the current design requires that
can you please elaborate?
this is not done. let me explore that |
if it not require then just remove it.
We have two types of requests, one from customers and other is background job. Thus wondering we can create two buckets for this, where customer request will get more preference but background job should not execute query requests more than n.
Same as above if not require just remove it. I think one param is more than enough?
that maybe helpful in two bucket scenario |
@@ -31,6 +33,7 @@ public class RateLimiterConfig { | |||
public int allowedRequests; | |||
public boolean isSlotBorrowingEnabled; | |||
public int guaranteedSlotsThreshold; | |||
public List<RateLimiterPayload.ReadBucketConfig> readBuckets; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My guess of readBuckets
nested inside RateLimiterConfig is to allow the json reader to handle both cases:
- no bucket, just configuration on the existing non bucket limiter:
"rate-limiters": {
"allowedRequests": 2,
"slotAcquisitionTimeoutInMS": 1000
}
- use bucket:
"rate-limiters": {
"readBuckets": [
{
"name": "test-bucket",
"conditions": [{
"queryParamPattern": {
"q-bucket": "test-bucket"
}
}],
"allowedRequests": 2,
"slotAcquisitionTimeoutInMS": 1000
}]
}
However, this could introduce some confusion as properties such as allowedRequests
could be defined either under each "readBuckets" and/or "rate-limiters".
The allowedRequests
defined under "rate-limiters" will be ignored if there are buckets. It seems all fields in RateLimiterConfig
will be ignored except readBuckets
, which lead me to think whether we should just use 2 separate class/config to avoid confusion and unused fields.
Could we just use something like check existence of rate-limiters
and rate-limiters-buckets
key to identify whether it's bucket and non-bucket use case (I think they are mutually exclusive) For example:
- No bucket usage
"rate-limiters": {
"allowedRequests": 2,
"slotAcquisitionTimeoutInMS": 1000
}
or
2. Bucket usage
"rate-limiters-buckets" : [
{
"name": "test-bucket",
"conditions": [{
"queryParamPattern": {
"q-bucket": "test-bucket"
}
}],
"allowedRequests": 2,
"slotAcquisitionTimeoutInMS": 1000
}
]
With this proposal the first case will be deserialized as RateLimiterConfig
, and the 2nd case will just be parsed as an array of ReadBucketConfig
, which might affect the ctor signature of RequestRateLimiter
(and child classes), more on this later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about it. This was done to simplify the code. Isn't it better to just warn the user if other properties are used?
|
||
@SuppressWarnings("unchecked") | ||
public BucketedQueryRateLimiter(RateLimiterConfig rateLimiterConfig) { | ||
super(rateLimiterConfig); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we can consider enhancing the RequestRateLimiter logic in the manager at here, instead of introducing BucketQueryRateLimiter
? It could avoid some code duplication, and unused Semaphore
in parent class QueryRateLimiter
.
It appears that we want the same ability as the existing QueryRateLimiter
in terms of throttling (or even borrowing as @hiteshk25 mentioned in another comment), so it might be handy to just re-use QueryRateLimiter/RequestRateLimiter
to handle bucketed limiter as well?
The idea is during the lookup, we could use a Matcher
to return the correct Rate limiter. For example for non bucket configuration, it will just be the existing code (using RequestType for simple lookup from the map), but for bucket configuration, it will use iterate and check for match similar to here? :)
And I ❤️ the new metrics added, perhaps we can add that to QueryRateLimiter
instead of just this class?
solr/core/src/java/org/apache/solr/servlet/BucketedQueryRateLimiter.java
Outdated
Show resolved
Hide resolved
According to the current design, the feature kicks in only if the header is present. if we remove it, it may not be backward compatible
There is already an implicit bucket which has an unlimited no:of threads. Only explicit bucket is just throttled. So, we should create a just a bucket for background tasks and limit the no:of operations and leave the rest as is |
Nice, then can we just accommodate header only? |
|
You mean, do not support parameters ? |
|
Solr-Request-Type: QUERY
?q-bucket=test-bucket